interface NotificationHandler {
  onerror?: (this: Notification, ev: Event) => any
  onclose?: () => void
  onclick?: () => void
  onshow?: () => void
}
class NotificationHelper {
  granted: boolean
  option: NotificationOptions & NotificationHandler
  constructor(opt = {}) {
    if ('Notification' in window) {
      this.granted = false
      let permission = Notification.permission
      switch (permission) {
        case 'default':
          Notification.requestPermission().then(permission => {
            this.granted = permission === 'granted'
          })
          break
        case 'granted':
          this.granted = true
          console.log('notification granted!')
          break
        case 'denied':
          console.log('notification denied!')
          break
        default:
          break
      }
    } else {
      this.granted = false
      console.log('not support notification!')
    }
    this.option = Object.assign(
      {
        // 通知显示正文。非必须，默认为空
        body: '',
        // 通知显示正文的图片地址。非必须，默认为空
        image: '',
        // 通知左侧图标。非必须，默认为空
        icon: '',
        // 通知的分类标记（ID）。非必须，默认为空
        tag: '',
        // 通知相关联的数据，通常用于方法的回调，传参。非必须，默认为空
        data: '',
        // 通知显示延迟的时间。非必须，默认通知实例创建完成就显示
        // timestamp: '',
        // 通知主体内容的水平展示顺序，有点类似direction属性。非必须，默认值是auto, 可以是ltr或rtl
        dir: 'auto' as NotificationDirection,
        // 当没有足够的空间来显示通知本身时，用于表示通知的图像的URL。非必须，默认为空
        badge: '',
        // 通知的语言。非必须默认为空
        lang: '',
        // 通知显示时，设备的振动模式。非必须，默认为空
        vibrate: [200, 100, 200],
        // 新通知出现是否覆盖旧的通知，覆盖（true）则永远只显示一条通知，不覆盖（false）则会多条通知重叠。非必须，默认为true
        renotify: false,
        // 通知是否静音。非必须，默认为false，表示无声
        silent: false,
        // 通知声源文件地址。非必须，默认为空
        sound: '',
        // 是否不在屏幕上显示通知信息。非必须，默认为false表示要显示
        noscreen: false,
        // 指定通知是否应该粘滞性，即不容易被用户清理。非必须，默认false表示不具粘滞性
        sticky: false,
        // 指定通知是否保持活性，知道用户点击或关闭。非必须，默认为false
        requireInteraction: false,
        onerror: function (ev: Event) {
          console.log('notification errored: ' + ev)
          throw ev
        },
        onclose: function () {
          console.log('notification closed')
        },
        onclick: function () {
          console.log('notification clicked')
        },
        onshow: function () {
          console.log('notification displayed！')
        }
      },
      opt
    )
  }
  push (opt: NotificationOptions & NotificationHandler) {
    if (this.granted) {
      let option = Object.assign({}, this.option, opt)
      const n = new Notification('Frame Lux', option)

      n.onshow = option.onshow!
      n.onclick = option.onclick!
      n.onclose = option.onclose!
      n.onerror = option.onerror!
      return n
    } else {
      console.log('notification denied!')
    }
  }
}

export default NotificationHelper
